package com.enlorenz.common.geo.analyzer.hotspot;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.enlorenz.common.geo.base.IPoint;
import com.enlorenz.common.geo.util.GeographyUtil;
import com.enlorenz.util.DataDetUtil;

/**
 * 抽象的热点分析
 * 通过制定的范围将点的集合进行分类
 * 将相隔制定范围的点归集在一种集合中
 * 并累计其范围内点的次数
 * 此分析可以将点按范围进行归类，
 * 用于判断点集中聚集的范围及聚集的频率
 * @author lcb
 */
public abstract class AbstractHotSpotAnalyzer {
	//热点范围
	private Integer areaDistance=500;
	/**
	 * 降序排序
	 */
	private static final Comparator comparatorDesc=new Comparator(){
		@Override
		public int compare(Object o1, Object o2) {
			HotSpotDetails s1=(HotSpotDetails)o1;
			HotSpotDetails s2=(HotSpotDetails)o2;
			return s2.getNum()-s1.getNum();
		}
	};
	
	/**
	 * 获取点列表
	 * @return
	 */
	protected abstract List<IPoint> getPointList();
	/**
	 * 获取点的唯一识别符
	 * @param point
	 * @return
	 */
	protected abstract String getPointUniKey(IPoint point);
	
	/**
	 * 创建热点集合
	 * @return
	 */
	protected HotSpotGather createHotSpotGather(IPoint point){
		return new HotSpotGather();
	}
	/**
	 * 创建热点细节
	 * @param point
	 * @return
	 */
	protected HotSpotDetails createHotSpotDetails(IPoint point){
		return new HotSpotDetails();
	}
	/**
	 * 添加新的热点细节
	 * @param hotSpotGather
	 * @param point
	 */
	protected void addHotSpotDetails(HotSpotGather hotSpotGather,IPoint point){
		HotSpotDetails details=createHotSpotDetails(point);
		details.setLon(point.getLon());
		details.setLat(point.getLat());
		details.setNum(1);
		hotSpotGather.getDetailsList().add(details);
		addDetailsOne(details, point);
	}
	/**
	 * 加入一条细节数据
	 * @param details
	 * @param point
	 */
	protected void addDetailsOne(HotSpotDetails details,IPoint point){
		
	}
	/**
	 * 设置点的范围
	 * @param areaDistance
	 */
	public void setAreaDistance(Integer areaDistance) {
		this.areaDistance = areaDistance;
	}
	
	/**
	 * 获取热点列表
	 * @return
	 */
	public ArrayList<HotSpotGather> getHotspotList(){
		//获取点列表
		List<IPoint> list = getPointList();
		if(DataDetUtil.isCollectionEmpty(list)){
			return null;
		}
		
		Map<String,HotSpotGather> data=new HashMap<String, HotSpotGather>();
		for(IPoint point:list){
			//获取点的唯一识别符
			String pointKey=getPointUniKey(point);
			HotSpotGather hotSpotGather=data.get(pointKey);
			if(null == hotSpotGather){
				hotSpotGather=createHotSpotGather(point);
				hotSpotGather.setCategoryKey(pointKey);
				data.put(pointKey, hotSpotGather);
			}
			
			if(DataDetUtil.isCollectionEmpty(hotSpotGather.getDetailsList())){
				//添加新的热点细节
				addHotSpotDetails(hotSpotGather,point);
			}else{
				boolean isApt=false;
				for(HotSpotDetails hsd: hotSpotGather.getDetailsList()){
					Double dis=GeographyUtil.computerDistanceFromPoint(hsd, point);
					if(dis<=areaDistance){
						hsd.setNum(hsd.getNum()+1);
						addDetailsOne(hsd, point);
						isApt=true;
					}
				}
				
				if(!isApt){
					addHotSpotDetails(hotSpotGather,point);
				}
				
			}
		}
		
		//进行降序排序
		for(HotSpotGather hsg:data.values()){
			Collections.sort(hsg.getDetailsList(), comparatorDesc);
		}
			
		return new ArrayList<HotSpotGather>(data.values());
	}
	
}
